using System;
using SharpMud.Net.Telnet;

namespace SharpMud.Net.Telnet.IAC
{
	/// <summary>
	/// Provides abstraction of an IAC control code in such a way that external systems may augment
	/// the basic set of IAC control codes.
	/// </summary>
	public class ControlCode
	{
		#region Private Variables
		private string	_Name;
		private byte	_Value;
		#endregion

		#region Constructors
		private ControlCode()
		{
		}
		public ControlCode(string name, byte value)
		{
			this._Name = name;
			this._Value = value;

			if(ControlCodeRegistry.GlobalInstance.Evaluate(this.Value)==null && Name!=String.Empty)
			{
				ControlCodeRegistry.GlobalInstance.Add(this);
			}
			if(ControlCodeRegistry.GlobalInstance.Evaluate(this.Name)==null && Name!=String.Empty)
			{
				ControlCodeRegistry.GlobalInstance.Add(this);
			}
		}
		#endregion

		#region Properties
		public virtual string	Name
		{
			get
			{
				if(_Name==String.Empty)
				{
					if(ControlCodeRegistry.GlobalInstance.Evaluate(this.Value)!=null)
					{
						this._Name = ControlCodeRegistry.GlobalInstance.Evaluate(this.Value).Name;
						return this._Name;
					}
					else
					{
						return String.Empty;
					}
				}
				else
					return this._Name;
			}
		}
		public virtual byte		Value
		{
			get
			{
				return this._Value;
			}
		}
		#endregion

		#region Conversions
		public byte	ToByte()
		{
			return this.Value;
		}
		public char ToChar()
		{
			return System.Convert.ToChar(this.Value);
		}

		public static explicit operator byte(ControlCode value)
		{
			return value.ToByte();
		}

		public static explicit operator char(ControlCode value)
		{
			return System.Convert.ToChar(value.ToByte());
		}

		public static explicit operator ControlCode(char value)
		{
			return (ControlCode)(System.Convert.ToByte(value));
		}

		public static explicit operator ControlCode(byte value)
		{
			ControlCode c = ControlCodeRegistry.GlobalInstance.Evaluate(value);
			if(c==null)
			{
				return new ControlCode("",value);
			}
			else
			{
				return c;
			}
		}
		#endregion

		#region Equality
		public override bool Equals(object obj)
		{
			if(obj is ControlCode)
			{
				return Equals((ControlCode)obj);
			}
			else
				return base.Equals(obj);
		}
		public bool Equals(ControlCode obj)
		{
			return Equals(this,obj);
		}
		public static bool Equals(ControlCode c1, ControlCode c2)
		{
			if(Object.Equals(c1,null) && Object.Equals(c2,null))
				return true;
			
			if(		(!Object.Equals(c1,null) && Object.Equals(c2,null)) 
				||	(Object.Equals(c1,null) && !Object.Equals(c2,null))
				)

				return false;
			if(c2.Value == c1.Value)
				return true;
			if((c2.Name==c1.Name) && c1.Name!=null && c1.Name!=String.Empty)
				return true;
			return false;
		}
		public static bool operator ==(ControlCode c1, ControlCode c2)
		{
			return Equals(c1,c2);
		}
		public static bool operator !=(ControlCode c1, ControlCode c2)
		{
			return !Equals(c1,c2);
		}
		#endregion
	}
}